Skip to content

Purge stale public.wsg_outlet references; document the ltree-closure trap - #243

Merged
NewGraphEnvironment merged 1 commit into
mainfrom
wsg-outlet-stale-refs
Aug 28, 2026
Merged

Purge stale public.wsg_outlet references; document the ltree-closure trap#243
NewGraphEnvironment merged 1 commit into
mainfrom
wsg-outlet-stale-refs

Conversation

@NewGraphEnvironment

Copy link
Copy Markdown
Owner

Summary

public.wsg_outlet was removed as a concept by #227/v0.45.1 (fresh 0.33.0 ships outlets and passes them as a VALUES list). References survived in places that still steer behaviour — including one in code I shipped in v0.45.0.

What was wrong

file problem
R/lnk_log.R listed public.wsg_outlet as a pipeline input primitive, so the run-provenance log fingerprints a table that should not exist — real numbers for a phantom dependency on a machine with the leftover table, NULLs on a clean one
research/study_areas.md documented the superseded technique as current — "closure and downstream-first order are derived from wscode_ltree ancestry (@>)" — and cited #227 as tracking the table's "reproducible build", when #227 was re-scoped to delete it
research/study_area_run.md, data-raw/study_area_run.sh referenced the removed table in prose/comments

data-raw/study_area_wsgs.R was already a shim around lnk_wsg_resolve(), so no live code path computed a wrong closure. The damage was documentation steering a reader into the trap.

The trap, now in RUNBOOK §8b

Two watershed groups on the same stream share an outlet code, so a.outlet @> b.outlet is true in both directions and reports each as downstream of the other. Closure is measure-aware, not code-aware — which is why c("PARS","BULK") dropped from 15 WSGs to 9 when #238 adopted fresh 0.33.0.

The worked example is the Kootenay, where it bites hardest. FWA carries the whole river under one continuous wscode_ltree = 300.625474, including the stretch that leaves BC near Newgate, runs through Montana and Idaho, and re-enters at Creston. Measures chain with no gap:

LARL 0–130 → KOTL 130–431,808 → BULL 431,808–495,206 → SMAR 495,206–608,735 → KOTR 608,735–773,149

So KOTR/SMAR/BULL are upstream of Kootenay Lake via the US loop — but an ltree test sees them sharing KOTL's outlet code and calls them downstream. The correct closure of c("LARL","KOTL","SLOC") is just those three: LARL is the terminal BC group (it holds the Kootenay's mouth at Castlegar and the Columbia down to the border — hence Waneta and Seven Mile sitting in it), and below it is the United States.

§8b also records that a public.wsg_outlet table found in any database is a leftover: it still answers queries, and answers them wrongly.

How it was found

By falling into it. A hand-rolled @> closure query produced a five-WSG "outstanding downstream closure" (KOTR, COLR, BULL, SMAR, UARL) that does not exist — caught when the geography was questioned, and confirmed by lnk_wsg_resolve() returning exactly the three groups already modelled.

Verification

devtools::test() on test-lnk_log.R — 128 pass. No behavioural change beyond dropping the phantom primitive from log_input.

🤖 Generated with Claude Code

https://claude.ai/code/session_014kSEJoad4Bc553qU8eFiE6

…trap

#227/v0.45.1 removed public.wsg_outlet as a concept, but references
survived in places that still steer behaviour:

- R/lnk_log.R listed public.wsg_outlet as a pipeline input primitive, so
  the run-provenance log (v0.45.0) fingerprints a table that should not
  exist. On a machine with the leftover table it records real numbers for
  a phantom dependency; on a clean one it records NULLs for a table that
  was never a dependency. Removed.
- research/study_areas.md documented the *superseded* technique as
  current -- "closure and downstream-first order are derived from
  wscode_ltree ancestry (@>)" -- and pointed at #227 as the issue
  tracking its reproducible build, when #227 was re-scoped to delete it.
  Rewritten to point at lnk_wsg_resolve() with an explicit do-not.
- research/study_area_run.md and data-raw/study_area_run.sh referenced
  the table in prose. Repointed. data-raw/study_area_wsgs.R was already
  a shim around lnk_wsg_resolve(), so no live code path was wrong.

Adds RUNBOOK section 8b, which did not previously warn about any of this.
The trap is that two watershed groups on the same stream share an outlet
code, so `a.outlet @> b.outlet` is true in both directions and reports
each as downstream of the other. Worked example is the Kootenay, where
FWA carries the out-and-back through Montana and Idaho under one
continuous wscode -- an ltree test puts KOTR/SMAR/BULL below Kootenay
Lake when they are above it via the US, and the true closure of
LARL/KOTL/SLOC is just those three.

Found by falling into it: a hand-rolled @> query produced a five-WSG
"outstanding downstream closure" that does not exist.
@NewGraphEnvironment
NewGraphEnvironment merged commit 430be0f into main Aug 28, 2026
1 check passed
@NewGraphEnvironment
NewGraphEnvironment deleted the wsg-outlet-stale-refs branch August 28, 2026 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant